/**=============================================================================
@file
   qhdsp_hvx_common.h

@brief
   Header file for common routines for complex and real HVX implementations of FFT and IFFT.

Copyright (c) 2020 Qualcomm Technologies Incorporated.
All Rights Reserved. Qualcomm Proprietary and Confidential.
=============================================================================**/

#ifndef _QHDSP_HVX_FFT_COMMON_H
#define _QHDSP_HVX_FFT_COMMON_H

#ifdef __cplusplus
extern "C" {
#endif

#include "qhcomplex.h"
#include "qhmath.h"
#include "hvx_fft_common.h"

/** Combine the 16 least significant bits of h and l into a 32-bit number, with the lower bits containing l and higher bits containing h*/
#define     combine(h, l)                   ((((h) & 0x0000ffff) << 16) | ((l) & 0x0000ffff) )
/** Combine the 16 least significant bits of var_i and var_r to create a 32-bit number representing a complex number with real part var_r in lower bits and imaginary part var_i in higher bits */
#define     create_complex(var_r, var_i)    (combine((var_i),(var_r)))


#define     M_PI                            3.14159265358979323846  /**< Pi, the ratio of a circle’s circumference to its diameter */

/** @defgroup qhdsp_hvx_fft_common_functions QHDSP_HVX FFT common functions
  * @brief QHDSP_HVX FFT common functions
  * @ingroup qhdsp_hvx_fft_functions
 *  @{
 */

/**
 * @brief           [HVX] Generate twiddle factors for [fixed-point] complex 1D FFT/IFFT functions.
 * @param[in,out]   twiddle - output buffer for storing generated twiddle factors
 * @param[in]       NP - number of points on which FFT/IFFT is performed
 * @param[in]       log2NP - logarithm of power 2 of number of points
 * @return
 * @note
 *                  - Generated twiddle factors are used for both FFT and IFFT.
 *                  - Code doesn't utilize HVX vector instructions/parallelism.
 *                  - twiddle factors format: Q1.14
 *                  - Assumptions:
 *                                  1. twiddle - buffer aligned by 128bytes
 *                                  2. twiddle buffer size is NP * [4bytes]
 */
void qhdsp_hvx_fft_gen_twiddles_complex_ach(int32_t* twiddle, uint32_t NP, uint32_t log2NP);

/**
 * @brief           [HVX] Generate twiddle factors for [fixed-point] real 1D FFT/IFFT functions.
 * @param[in,out]   twiddle1 - output buffer for storing generated twiddle factors - for N/2-point complex FFT
 * @param[in,out]   twiddle2 - output buffer for storing generated twiddle factors - for last stage
 * @param[in]       NP - number of points on which FFT/IFFT is performed
 * @param[in]       log2NP - logarithm of power 2 of number of points
 * @note
 *                  - Generated twiddle factors are used for both FFT and IFFT.
 *                  - Code doesn't utilize HVX vector instructions/parallelism.
 *                  - twiddle1 factors format: Q1.14
 *                  - twiddle2 factors format: Q15
 *                  - Assumptions:
 *                                  1. twiddle1 & twiddle2 - buffers aligned by 128bytes
 *                                  2. twiddle1 & twiddle2 - buffer size is NP * [4bytes]
 */
void qhdsp_hvx_fft_gen_twiddles_real_ach(int32_t* twiddle1, int32_t* twiddle2, uint32_t NP, uint32_t log2NP);

/**
 * @brief           [HVX] Generate twiddle factors for [fixed-point] real 2D FFT/IFFT functions.
 * @param[in,out]   twiddle1 - output buffer for storing generated twiddle factors - for N/2-point complex FFT
 * @param[in,out]   twiddle2 - output buffer for storing generated twiddle factors - for last stage
 * @param[in]       NP - number of points on which FFT/IFFT is performed
 * @param[in]       log2NP - logarithm of power 2 of number of points
 * @note
 *                  - Generated twiddle factors are used for both FFT and IFFT.
 *                  - Code doesn't utilize HVX vector instructions/parallelism.
 *                  - twiddle1 factors format: Q1.14
 *                  - twiddle2 factors format: Q15
 *                  - Assumptions:
 *                                  1. twiddle1 & twiddle2 - buffers aligned by 128bytes
 *                                  2. twiddle1 - buffer size is NP * [4bytes]
 *                                  2. twiddle2 - buffer size is NP/2 * [4bytes]
 */
void qhdsp_hvx_2D_fft_gen_twiddles_real_ach(int32_t* twiddle1, int32_t* twiddle2, uint32_t NP, uint32_t log2NP);

/**
 * @brief           [HVX] Generate twiddle factors for [float-point] complex 1D FFT/IFFT functions.
 * @param[in,out]   twiddle - output buffer for storing generated twiddle factors
 * @param[in]       NP - number of points on which FFT/IFFT is performed
 * @param[in]       log2NP - logarithm of power 2 of number of points
 * @return
 * @note
 *                  - Generated twiddle factors are used for both FFT and IFFT.
 *                  - Code doesn't utilize HVX vector instructions/parallelism.
 *                  - Assumptions:
 *                                  1. twiddle - buffer aligned by 128bytes
 *                                  2. twiddle buffer size is NP * [8bytes]
 */
void qhdsp_hvx_fft_gen_twiddles_complex_acf(float complex* twiddle, uint32_t NP, uint32_t log2NP);

/**
 * @brief           [HVX] Generate twiddle factors for [float-point] real 1D FFT/IFFT functions.
 * @param[in,out]   twiddle1 - output buffer for storing generated twiddle factors - for N/2-point complex FFT
 * @param[in,out]   twiddle2 - output buffer for storing generated twiddle factors - for last stage
 * @param[in]       np - number of points on which FFT/IFFT is performed
 * @param[in]       log2np - logarithm of power 2 of number of points
 * @note
 *                  - Generated twiddle factors are used for both FFT and IFFT.
 *                  - Code doesn't utilize HVX vector instructions/parallelism.
 *                  - Assumptions:
 *                                  1. twiddle1 & twiddle2 - buffers aligned by 128bytes
 *                                  2. twiddle1 & twiddle2 - buffer size is NP * [8bytes]
 */
void qhdsp_hvx_fft_gen_twiddles_real_acf(float complex *twiddle1, float complex *twiddle2, uint32_t np, uint32_t log2np);

/**
 * @brief           [HVX] Generate twiddle factors for [float-point] real 2D FFT/IFFT functions.
 * @param[in,out]   twiddle1 - output buffer for storing generated twiddle factors - for N/2-point complex FFT
 * @param[in,out]   twiddle2 - output buffer for storing generated twiddle factors - for last stage
 * @param[in]       NP - number of points on which FFT/IFFT is performed
 * @param[in]       log2NP - logarithm of power 2 of number of points
 * @note
 *                  - Generated twiddle factors are used for both FFT and IFFT.
 *                  - Code doesn't utilize HVX vector instructions/parallelism.
 *                  - Assumptions:
 *                                  1. twiddle1 & twiddle2 - buffers aligned by 128bytes
 *                                  2. twiddle1 - buffer size is NP * [8bytes]
 *                                  2. twiddle2 - buffer size is NP/2 * [8bytes]
 */
void qhdsp_hvx_2D_fft_gen_twiddles_real_acf(float complex* twiddle1, float complex* twiddle2, uint32_t NP, uint32_t log2NP);

/**
 * @brief           [HVX] Generate twiddle factors for [half precision float-point] complex 1D FFT/IFFT functions.
 * @param[in,out]   twiddle - output buffer for storing generated twiddle factors
 * @param[in]       NP - number of points on which FFT/IFFT is performed
 * @param[in]       log2NP - logarithm of power 2 of number of points
 * @return
 * @note
 *                  - Generated twiddle factors are used for both FFT and IFFT.
 *                  - Code doesn't utilize HVX vector instructions/parallelism.
 *                  - Assumptions:
 *                                  1. twiddle - buffer aligned by 128bytes
 *                                  2. twiddle buffer size is NP * [4bytes]
 */
void qhdsp_hvx_fft_gen_twiddles_complex_achf(qhl_cfloat16_t* twiddle, uint32_t NP, uint32_t log2NP);

/**
 * @brief           [HVX] Generate twiddle factors for [half precision float-point] real 1D FFT/IFFT functions.
 * @param[in,out]   twiddle1 - output buffer for storing generated twiddle factors - for N/2-point complex FFT
 * @param[in,out]   twiddle2 - output buffer for storing generated twiddle factors - for last stage
 * @param[in]       np - number of points on which FFT/IFFT is performed
 * @param[in]       log2np - logarithm of power 2 of number of points
 * @note
 *                  - Generated twiddle factors are used for both FFT and IFFT.
 *                  - Code doesn't utilize HVX vector instructions/parallelism.
 *                  - Assumptions:
 *                                  1. twiddle1 & twiddle2 - buffers aligned by 128bytes
 *                                  2. twiddle1 & twiddle2 - buffer size is NP * [4bytes]
 */
void qhdsp_hvx_fft_gen_twiddles_real_achf(qhl_cfloat16_t *twiddle1, qhl_cfloat16_t *twiddle2, uint32_t np, uint32_t log2np);

/**
 * @brief           [HVX] Generate twiddle factors for [half precision float-point] real 2D FFT/IFFT functions.
 * @param[in,out]   twiddle1 - output buffer for storing generated twiddle factors - for N/2-point complex FFT
 * @param[in,out]   twiddle2 - output buffer for storing generated twiddle factors - for last stage
 * @param[in]       NP - number of points on which FFT/IFFT is performed
 * @param[in]       log2NP - logarithm of power 2 of number of points
 * @note
 *                  - Generated twiddle factors are used for both FFT and IFFT.
 *                  - Code doesn't utilize HVX vector instructions/parallelism.
 *                  - Assumptions:
 *                                  1. twiddle1 & twiddle2 - buffers aligned by 128bytes
 *                                  2. twiddle1 - buffer size is NP * [4bytes]
 *                                  2. twiddle2 - buffer size is NP/2 * [4bytes]
 */
void qhdsp_hvx_2D_fft_gen_twiddles_real_achf(qhl_cfloat16_t* twiddle1, qhl_cfloat16_t* twiddle2, uint32_t NP, uint32_t log2NP);

/**
  * @}
  */

#ifdef __cplusplus
}
#endif

#endif /* _QHDSP_HVX_FFT_COMMON_H */
